#ifndef __NEZHA_EXCEPTION_H__
#define __NEZHA_EXCEPTION_H__

#pragma once

#include "EngineCompileConfig.h"
#include <exception>

#define NEZHA_EXCEPTION_FLAG				1
#define NEZHA_EXCEPTION_LOG			0x1
#define NEZHA_EXCEPTION_DIALOG		0x2

// define full exception features
#define NEZHA_EXCEPTION_CONFIG 3

namespace Nezha
{

	class NEZHA_ENGINE_ENTRY NZExceptionCatgory
	{
	public:
		NZExceptionCatgory();
		NZExceptionCatgory(const String& catName);

		const String& getName() const
		{
			return mName;
		}

	private:
		String mName;
	};

	class NEZHA_ENGINE_ENTRY NZException : public std::exception
	{
	public:
		NZException(const String& desc);

		NZException(const String& desc, const NZExceptionCatgory& cat, const String& file, int line);

		NZException(const NZException& rhs);

		~NZException() throw() {}

		NZException& operator = (const NZException& rhs);

		// default built-in exception catgorys
		static NZExceptionCatgory IOError;					//
		static NZExceptionCatgory InvalidParam;
		static NZExceptionCatgory InvalidState;
		static NZExceptionCatgory DumplicateItem;
		static NZExceptionCatgory ItemNotFound;
		static NZExceptionCatgory DependenciesError;		// error caused by dependencies moudle or API
		static NZExceptionCatgory Assertion;
		static NZExceptionCatgory Unknown;

NEZHA_INTERNAL:
		int mLine;
		NZExceptionCatgory mCatgory;
		String mDesc;
		String mFile;

	};

#if NEZHA_EXCEPTION_FLAG == 1

#	define NEZHA_EXCEPTION(cat, desc) throw NZException(desc, cat, __FILE__, __LINE__)

#else

#	define NEZHA_EXCEPTION(cat, desc)

#endif

#ifdef NEZHA_WITHOUT_ASSERT

#define NZ_ASSERT
#define NZ_ASSERT_EX

#else

#	ifdef USING_STANDARD_ASSERT

#		define NZ_ASSERT assert

#	else

#		define NZ_ASSERT(cond) if(!(cond))(NEZHA_EXCEPTION(NZException::Assertion, ""))

#	endif

#define NZ_ASSERT_EX(cond, desc) if(!(cond))(NEZHA_EXCEPTION(NZException::Assertion, desc))

#endif

}//end namespace Nezha

#endif //end __NEZHA_EXCEPTION_H__